package com.smart.system.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.smart.common.constant.GlobalConstants;
import com.smart.common.core.domain.entity.SysDept;
import com.smart.common.exception.ServiceException;
import com.smart.common.utils.DateUtils;
import com.smart.common.utils.SecurityUtils;
import com.smart.common.utils.StringUtils;
import com.smart.system.domain.Employee;
import com.smart.system.domain.WorkingSchedule;
import com.smart.system.domain.vo.AttendanceVo;
import com.smart.system.service.IEmployeeService;
import com.smart.system.service.ISysDeptService;
import com.smart.system.service.IWorkingScheduleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.system.mapper.AttendanceRecordMapper;
import com.smart.system.domain.AttendanceRecord;
import com.smart.system.service.IAttendanceRecordService;

/**
 * 考勤记录Service业务层处理
 * 
 * @author smart
 * @date 2024-09-18
 */
@Service
public class AttendanceRecordServiceImpl extends ServiceImpl<AttendanceRecordMapper,AttendanceRecord> implements IAttendanceRecordService {

    @Autowired
    private IWorkingScheduleService workingScheduleService;

    @Autowired
    private IEmployeeService employeeService;

    @Autowired
    private ISysDeptService sysDeptService;

    /**
     * 查询考勤记录列表
     * 
     * @param attendanceRecord 考勤记录
     * @return 考勤记录
     */
    @Override
    public IPage<AttendanceRecord> selectAttendanceRecordList(AttendanceRecord attendanceRecord,Page<AttendanceRecord> page)
    {
        if (SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
            page = this.page(page,Wrappers.lambdaQuery(AttendanceRecord.class)
                    .like(StringUtils.isNotEmpty(attendanceRecord.getUserName()), AttendanceRecord::getUserName, attendanceRecord.getUserName())
                    .eq(StringUtils.isNotEmpty(attendanceRecord.getAttendance()), AttendanceRecord::getAttendance, attendanceRecord.getAttendance())
                    .apply(ObjectUtils.isNotEmpty(attendanceRecord.getAttendanceDate()), "'" + attendanceRecord.getAttendanceDate() + "' = date_format(attendance_date, '%Y-%m-%d')")
                    .orderByDesc(AttendanceRecord::getAttendanceDate)
            );
        }else{
            List<SysDept> sysDepts = sysDeptService.listDeptChildById(SecurityUtils.getDeptId());

            page = this.page(page,Wrappers.lambdaQuery(AttendanceRecord.class)
                    .in(sysDepts.size()>0,AttendanceRecord::getDeptId,sysDepts.stream().map(SysDept::getDeptId).collect(Collectors.toList()))
                    .like(StringUtils.isNotEmpty(attendanceRecord.getUserName()), AttendanceRecord::getUserName, attendanceRecord.getUserName())
                    .eq(StringUtils.isNotEmpty(attendanceRecord.getAttendance()), AttendanceRecord::getAttendance, attendanceRecord.getAttendance())
                    .apply(ObjectUtils.isNotEmpty(attendanceRecord.getAttendanceDate()), "'" + attendanceRecord.getAttendanceDate() + "' = date_format(attendance_date, '%Y-%m-%d')")
                    .orderByDesc(AttendanceRecord::getAttendanceDate)
            );
        }

        List<Integer> employeeIds = page.getRecords().stream().map(AttendanceRecord::getUserId).collect(Collectors.toList());
        if (employeeIds.size()>0) {
            List<Employee> employees = employeeService.listByIds(employeeIds);
            for (AttendanceRecord record : page.getRecords()) {
                //获取员工岗位
                for (Employee employee : employees) {
                    if (record.getUserId().equals(employee.getId())) {
                        record.setPosition(employee.getPosition());
                        record.setPositionName(employee.getPositionName());
                    }
                }
            }
        }
        return page;
    }

    /**
     * 补卡
     * 
     * @param userId
     * @return 结果
     */
    @Override
    public int updateAttendanceRecord(Integer userId,Date date,Integer type)
    {
        String dateStr1 = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date);
        AttendanceRecord one = this.getOne(Wrappers.lambdaQuery(AttendanceRecord.class)
                .eq(AttendanceRecord::getUserId,userId)
                .apply("attendance_date =DATE_FORMAT('"+dateStr1+"', '%Y-%m-%d')").last("limit 1"));
        if(one == null){
            throw new ServiceException("没有此考勤记录!");
        }
        Employee employee = employeeService.selectEmployeeById(String.valueOf(userId));
        //获取本部门上班下班打卡时间
        WorkingSchedule workingSchedule = workingScheduleService.getOne(Wrappers.lambdaQuery(WorkingSchedule.class).eq(WorkingSchedule::getDeptId,employee.getDeptId()).last("limit 1"));

        //获取当天是否需要上班
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        List array = workingSchedule.getArray();
        if (!array.contains(dayOfWeek)) {
            throw new ServiceException("此日期不需要上班!");
        }
        //全天卡
        if(type==null||type == 3){
            String dateStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date);
            dateStr+=" "+workingSchedule.getWorkStartUpTime();
            try {
                one.setAttendanceUpTime(DateUtils.parseDate(dateStr,DateUtils.YYYY_MM_DD_HH_MM_SS));
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }

            dateStr1+=" "+workingSchedule.getWorkEndUpTime();
            try {
                one.setAttendanceDownTime(DateUtils.parseDate(dateStr1,DateUtils.YYYY_MM_DD_HH_MM_SS));
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
            one.setAttendance(GlobalConstants.ATTENDANCE_NORMAL);
        }else{
            //上班卡
            if(type == 0){
                String dateStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date);
                dateStr+=" "+workingSchedule.getWorkStartUpTime();
                try {
                    one.setAttendanceUpTime(DateUtils.parseDate(dateStr,DateUtils.YYYY_MM_DD_HH_MM_SS));
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }
            //下班卡
            if(type == 1){
                String dateStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date);
                dateStr+=" "+workingSchedule.getWorkEndUpTime();
                try {
                    one.setAttendanceDownTime(DateUtils.parseDate(dateStr,DateUtils.YYYY_MM_DD_HH_MM_SS));
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        one.setIsRepair(GlobalConstants.IS_REPAIR_TRUE);
        one.setReplacementDate(DateUtils.getNowDate());
        one.setUpdateTime(DateUtils.getNowDate());
        one.setUpdateBy(SecurityUtils.getUsername());
        this.updateById(one);
        return 1;
    }

    @Override
    public AttendanceVo attendance(Integer userId, Date startTime, Date endTime) {
        //获取所有天数的数据
        List<AttendanceRecord> list = this.list(Wrappers.lambdaQuery(AttendanceRecord.class)
                .eq(userId!=null,AttendanceRecord::getUserId,userId)
                .apply(startTime != null,"attendance_date >= '"+ DateUtils.dateTime(startTime)+"'")
                .apply(endTime != null,"attendance_date <= '"+ DateUtils.dateTime(endTime)+"'")
                .apply("attendance is not null")
        );
        AttendanceVo vo = AttendanceVo.init();
        for (AttendanceRecord attendanceRecord : list) {
            switch (attendanceRecord.getAttendance()) {
                case GlobalConstants.ATTENDANCE_NORMAL:
                    // 处理正常出勤逻辑
                    vo.setNormal(vo.getNormal()+1);
                    break;
                case GlobalConstants.ATTENDANCE_LATE:
                    // 处理迟到逻辑
                    vo.setLate(vo.getLate()+1);
                    break;
                case GlobalConstants.ATTENDANCE_ABSENTEEISM:
                    vo.setAbsenteeism(vo.getAbsenteeism()+1);
                    // 处理旷工逻辑
                    break;
                case GlobalConstants.ATTENDANCE_LEAVE:
                    // 处理请假逻辑
                    vo.setLeave(vo.getLeave()+1);
                    break;
                case GlobalConstants.ATTENDANCE_EXCEPTION:
                    // 处理异常情况逻辑
                    vo.setAbnormal(vo.getAbnormal()+1);
                    break;
                case GlobalConstants.ATTENDANCE_REST:
                    // 处理休息逻辑
                    vo.setRest(vo.getRest()+1);
                    break;
                default:
                    // 如果有其他未知状态，可以在这里处理
                    break;
            }
        }
        return vo;
    }
}
